<?php
namespace Lib\src;

/**
 * Created by PhpStorm.
 * User: Se1per
 * Date: 2023/5/25
 * Time: 23:49
 */
class Validator
{
    // 需要验证得属性
    protected $data;
    // 验证规则
    protected $rules = [];
    // 验证结果
    protected $errors = [];
    // 自定义返回描述
    protected $messages = [];

    /**
     * 验证器 还缺少查询数据库是否有重复 在控制器简单实现,暂不添加到 验证器中,(实现方法也很简单,封装好拼接sql 和调用封装好得 DB 类或者 mysqli 类)
     * @param array $data
     * @param array $rules
     * @param array $messages
     */
    public function __construct(array $data,array  $rules , array $messages = []) {
        $this->data = $data;
        $this->rules = $rules;
        $this->messages = $messages;
        return $this;
    }

    /**
     * 高仿 laravel 验证器
     * @return array
     * @throws \Exception
     */
    public function validate(): array
    {
        foreach ($this->rules as $field => $rule) {
            if (array_key_exists($field, $this->data)) {
                $value = trim($this->data[$field]);
            }

            $ruleArray = explode('|', $rule);
            
            // 处理 Rule::delimiters 的情况
            if (!is_array($ruleArray)) {
                throw new \Exception('Rule delimiter not found: ' . var_export($rule, true));
            }

            foreach ($ruleArray as $validation) {
                if (strstr($validation, ":")) {
                    list($method, $param) = explode(':', $validation);
                    // 调用对应方法并传入参数验证数据，并将结果保存到 errors 数组中
                    if (!$this->$method($value, intval($param))) {
                        if(isset($this->messages[$field.'.'.$method])){
                            $error = $this->messages[$field.'.'.$method];
                        }else{
                            $error = "$field :. 规则无法通过";
                        }
                        array_push($this->errors, "{$field}：$error"); // 添加自定义错误信息到错误数组
                    }
                } else {
                    if (!$this->$validation($value, null)) {
                        if(isset($this->messages[$field.'.'.$validation])){
                            $error = $this->messages[$field.'.'.$validation];
                        }else{
                            $error = "$field : $validation . 规则无法通过";
                        }

                        array_push($this->errors, "{$field}：$error"); // 添加自定义错误信息到错误数组

                    }
                }
                $value = '';
            }
        }

        if(empty($this->errors)){
            return [true,'验证成功'];
        }else{
            return [false,$this->errors];
        }
    }

    public function errors() {
        return implode("<br>", $this->errors);
    }

    // 验证规则对应的方法
    protected function required($value): bool
    {
        return !empty($value);
    }

    protected function email($value) {
        if(empty($value)) return true;
        return filter_var($value, FILTER_VALIDATE_EMAIL);
    }

    protected function maxlength($value, $length): bool
    {
        if(empty($value)) return true;
        return strlen(trim($value)) <= $length;
    }

    protected function minlength($value, $length): bool
    {
        if(empty($value)) return true;
        return strlen(trim($value)) >= $length;
    }

    public function mobile($value): bool
    {
        if(empty($value)) return true;

        // Check if phone number contains uppercase letters, lowercase letters, and special characters
        if (!preg_match('/^1[3456789][0-9]{9}$/', $value)) {
            return false;
        }
        return true;
    }
}